﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using System.ComponentModel;
using Microsoft.Xna.Framework.Input;

namespace The_LarX
{
    public class RotatedCamera : Camera3D
    {
#if WINDOWS
        [Category("Transformação")]
        [Description("A velocidade de movimentação da Câmera")]
#endif
        public float MovementSpeed
        {
            get { return speed; }
            set { speed = value; }
        }
        protected float speed = 30;

        public bool Active = false;
        
        #region Rotation
        public float LeftRightRot = MathHelper.PiOver2;
        public float UpDownRot = -MathHelper.Pi / 10.0f;
        protected float rotationSpeed = 5;
      
        public float RotationSpeed
        {
            get { return rotationSpeed; }
            set { rotationSpeed = value; }
        }        
        #endregion

        public RotatedCamera(GameScreen Screen)
            : base(Screen)
        {
            FarPlane = 100;
            Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, Engine.AspectRatio, 1.0f, 100);

            Position = new Vector3(0, 5, 0);

            Target = new Vector3(0, 0, 0);        
            UpdateViewMatrix();            
        }
        public RotatedCamera(Renderer Renderer, GameScreen Screen)
            : base(Renderer, Screen)
        {
            FarPlane = 100;
            Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, Engine.AspectRatio, 1.0f, 100);

            Position = new Vector3(0, 5, 0);

            Target = new Vector3(0, 0, 0);
            UpdateViewMatrix();
        }
        public RotatedCamera()
        {
            FarPlane = 100;
            Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, Engine.AspectRatio, 1.0f, 100);

            Position = new Vector3(0, 5, 0);

            Target = new Vector3(0, 0, 0);
            UpdateViewMatrix();            
        }

        public override void Update()
        {
            Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, Engine.AspectRatio, 1.0f, FarPlane);

            base.Update();

            UpdateViewMatrix();

            this.LeftRightRot = Actor.RadiansRotation.Y;
            this.UpDownRot = Actor.RadiansRotation.X;            
        }

        private void UpdateViewMatrix()
        {
            Matrix cameraRotation = Matrix.CreateRotationX(UpDownRot) * Matrix.CreateRotationY(LeftRightRot);

            Vector3 cameraOriginalTarget = new Vector3(0, 0, -1);
            Vector3 cameraRotatedTarget = Vector3.Transform(cameraOriginalTarget, cameraRotation);
            Vector3 cameraFinalTarget = Position + cameraRotatedTarget;

            Vector3 cameraOriginalUpVector = new Vector3(0, 1, 0);
            Vector3 cameraRotatedUpVector = Vector3.Transform(cameraOriginalUpVector, cameraRotation);

            View = Matrix.CreateLookAt(Position, cameraFinalTarget, cameraRotatedUpVector);
            this.Target = cameraFinalTarget;
        }

        public override void SetToInitialState()
        {
            base.SetToInitialState();

            Actor.SetToInitialState();
        }
               

        public override void SerializeData()
        {
            base.SerializeData();

            Data.AddData("RotatedCamera.Position", this.Position);
            Data.AddData("RotatedCamera.Target", this.Target);
            Data.AddData("RotatedCamera.LeftRightRot", this.LeftRightRot);
            Data.AddData("RotatedCamera.UpDownLot", this.UpDownRot);
        }
        public override void DeserializeData()
        {
            base.DeserializeData();

            this.Position = Data.GetData<Vector3>("RotatedCamera.Position");
            this.Target = Data.GetData<Vector3>("RotatedCamera.Target");
            this.LeftRightRot = Data.GetData<float>("RotatedCamera.LeftRightRot");
            this.UpDownRot = Data.GetData<float>("RotatedCamera.UpDownLot");

            Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, Engine.AspectRatio, 1.0f, FarPlane);
        }
    }
}